package ihm.panel.admin;

import ihm.applet.KrakenApplet;
import ihm.panel.TablePanel;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

import tools.AppletConstant;
import tools.PasswordSecurity;
import tools.StringUtils;

import bdd.sql.server.bean.User;
import bdd.sql.server.bean.User_Log;

import enumTypes.Civility;
import enumTypes.Rank;

/**
 * Panneau qui liste les utilisateurs dans une JTable.
 * @author Guillaume Pocas & Jean-Fraçois Augé
 */
public class ListUsersPanel extends TablePanel implements ActionListener {

	private static final long serialVersionUID = 1L;

	private KrakenApplet applet;

	private DefaultTableModel model;
	private JTable table;
	private static String[] COLUMN_NAMES = {"ID", "Mail", "Civilité", "Nom", "Prénom", "Rang", "Première Connexion"};

	private JPanel bottom_jp;
	private JButton add_jb, delete_jb, right_jb;

	/**
	 * Constructeur.
	 * @param applet
	 */
	public ListUsersPanel(KrakenApplet applet) {
		super();
		this.applet = applet;
		setLayout(new BorderLayout());

		// Table part!
		model = new DefaultTableModel(populateModel(), COLUMN_NAMES);
		model.addTableModelListener(this);

		table = new JTable(model) {
			private static final long serialVersionUID = 1L;

			//  Returning the Class of each column will allow different
			//  renderers to be used based on Class
			@SuppressWarnings({ "unchecked", "rawtypes" })
			public Class getColumnClass(int column) {
				return getValueAt(0, column).getClass();
			}

			//  Les deux premières colonnes ne sont pas modifiables
			public boolean isCellEditable(int row, int column) {
				int modelColumn = convertColumnIndexToModel(column);
				return (modelColumn == 0 || modelColumn == 1) ? false : true;
			}
		};
		table.setPreferredScrollableViewportSize(table.getPreferredSize());
		table.setFillsViewportHeight(true);

		TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
		table.setRowSorter(sorter);

		table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JComboBox<Civility>(Civility.values())));
		table.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(new JComboBox<Rank>(Rank.values())));

		JScrollPane scrollPane = new JScrollPane(table);
		add(scrollPane, BorderLayout.CENTER);

		// Buttons part!
		bottom_jp = new JPanel();

		add_jb = new JButton("Ajouter");
		add_jb.addActionListener(this);
		add_jb.setPreferredSize(AppletConstant.BUTTON_SIZE);
		bottom_jp.add(add_jb);

		delete_jb = new JButton("Supprimer");
		delete_jb.addActionListener(this);
		delete_jb.setPreferredSize(AppletConstant.BUTTON_SIZE);
		bottom_jp.add(delete_jb);

		right_jb = new JButton("Droits");
		right_jb.addActionListener(this);
		right_jb.setPreferredSize(AppletConstant.BUTTON_SIZE);
		bottom_jp.add(right_jb);

		add(bottom_jp, BorderLayout.SOUTH);
	}
	
	/**
	 * Retourne les IDs des élements selectionnés.
	 * @param rowStart
	 * @param rowEnd
	 * @return the IDs from the selected rows.
	 */
	public int[] getSelectedIDs(int rowStart, int rowEnd) {
		int[] selection = new int[rowEnd-rowStart+1];
		for(int i=0; i<rowEnd-rowStart+1; i++) {
			selection[i] = (int) model.getValueAt(
					table.convertRowIndexToModel(rowStart+i),
					table.convertColumnIndexToModel(0));
		}
		return selection;
	}

	/**
	 * Efface les IDs dans la base de données.
	 * @param ids
	 */
	public void deleteRows(int[] ids) {
		Session session = applet.getSession();
		Transaction tx = session.beginTransaction();
		for(int i : ids) {
			System.out.println("Deleting "+i);
			User user = (User) session.load(User.class, i);
			
			List<User_Log> resultats = session.createCriteria(User_Log.class).add(Restrictions.eq("user.id", user.getUser_id())).list();
			for(User_Log log : resultats)
				session.delete(log);

			session.delete(user);
		}
		tx.commit();
		session.close();
	}

	@Override
	public Object[][] populateModel() {
		Session session = applet.getSession();

		@SuppressWarnings("unchecked")
		List<User> resultats = session.createCriteria(User.class).list();
		Object[][] data = new Object[resultats.size()][COLUMN_NAMES.length];

		for(int i = 0; i < resultats.size(); i++) {
			data[i][0] = resultats.get(i).getUser_id();
			data[i][1] = resultats.get(i).getUser_mail();
			
			/*if(resultats.get(i).getUser_civil().equals(Civility.Madame))
				table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JComboBox<Civility>(Civility.values())));
			else if(resultats.get(i).getUser_civil().equals(Civility.Mademoiselle))
				table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JComboBox<Civility>(Civility.values())));
			else
				table.getColumnModel().getColumn(2).setCellEditor(new DefaultCellEditor(new JComboBox<Civility>(Civility.values())));*/
			data[i][2] = resultats.get(i).getUser_civil();
			
			data[i][3] = resultats.get(i).getUser_lastname();
			data[i][4] = resultats.get(i).getUser_name();
			
			/*if(resultats.get(i).getUser_rank().equals(Rank.Administrateur))
				table.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(new JComboBox<Rank>(Rank.values())));
			else
				table.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(new JComboBox<Rank>(Rank.values())));*/
			data[i][5] = resultats.get(i).getUser_rank();
			
			if(resultats.get(i).getUser_firstcon() == 1)
				data[i][6] = true;
			else
				data[i][6] = false;
		}
		
		session.close();
		return data;
	}

	@Override
	public void updateTableInfo() {
		setLocked(true);
		model.setDataVector(populateModel(), COLUMN_NAMES);
		setLocked(false);
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource().equals(add_jb))
			((AdministrationPanel) getParent()).setPanel("Ajouter");
		else if(e.getSource().equals(delete_jb)) {
			if(table.getSelectedRowCount() > 0) {
				int[] rows = table.getSelectedRows();
				int[] ids = new int[table.getSelectedRowCount()];

				for(int i=0; i<table.getSelectedRowCount(); i++)
					ids[i] = (int) model.getValueAt(table.convertRowIndexToModel(rows[i]), 0);

				deleteRows(ids);
				updateTableInfo();
			}
		}
		else if(e.getSource().equals(right_jb)) {
			if(table.getSelectedRowCount() > 0) {
				int id = getSelectedIDs(table.getSelectedRows()[0], table.getSelectedRows()[0])[0];
				Session session = applet.getSession();
				User user = (User) session.load(User.class, id);
				((AdministrationPanel) getParent()).getRightPanel().setUserID(user.getUser_id());
				((AdministrationPanel) getParent()).setPanel("Droits");
				System.out.println("Loading right panel with "+user.getUser_mail());
				session.close();
			}
		}
	}

	@Override
	public void tableChanged(TableModelEvent e) {
		System.out.println("tableChanged!");
		if(!isLocked()) {
			int row = e.getFirstRow();
			int column = e.getColumn();
			TableModel model = (TableModel) e.getSource();
			String columnName = model.getColumnName(column);
			Object data = model.getValueAt(row, column);

			System.out.println("changed value at "+row+", "+column);
			System.out.println(columnName+" is now "+data);


			Session session = applet.getSession();
			int id = (int) model.getValueAt(row, 0);
			User u = (User) session.load(User.class, id);
			Transaction tx = session.beginTransaction();

			u.setUser_civil((Civility) model.getValueAt(row, 2));
			u.setUser_lastname((String) model.getValueAt(row, 3));
			u.setUser_name((String) model.getValueAt(row, 4));
			u.setUser_rank((Rank) model.getValueAt(row, 5));
			// TODO vérifier que c'est correcte
			//u.setUser_firstcon((Boolean) model.getValueAt(row, 6));
			if((Boolean) model.getValueAt(row, 6))
				u.setUser_firstcon(1);
			else
				u.setUser_firstcon(0);
			//if(u.getUser_firstcon())
				//u.setUser_pwd(PasswordSecurity.sha256(u.getUser_pwd_default(), ""));
			//String seed = StringUtils.generateRandomString(12);
			if(u.getUser_firstcon() == 1) {
				byte[] hash = PasswordSecurity.sha256_2(u.getUser_pwd_default(), u.getUser_seedPwd());
				String b64 = StringUtils.toBase64(hash);
				u.setUser_pwd(b64);
				System.out.println(b64);
				
				//byte[] password = PasswordSecurity.sha256_2(u.getUser_pwd_default(), seed);
				//u.setUser_pwd(StringUtils.bytesToString(password));
				//u.setYes_pwd(u.getUser_pwd_default());
				//u.setUser_seedPwd(seed);
			}

			session.save(u);
			tx.commit();
			session.close();
		}
	}

}
